from math import radians, cos, sin
from itertools import product


def get_polygon_vertices(length, sides):
    angle = radians(360 / sides)
    # Функция для получения координат вершин правильного многоугольника
    for i in range(sides):
        a = i * angle        # Вычисляем угол для текущей вершины
        x = length * cos(a)  # Вычисляем координату X
        y = length * sin(a)  # Вычисляем координату Y
        yield [x, y]         # Добавляем координаты в список вершин


def move_polygon(vertices: list, d_vector: tuple):
    assert len(vertices[0]) == len(d_vector), "both dimensions must be equal to each other"
    for vertice, coordinate in product(vertices,  range(len(d_vector))):
        vertice[coordinate] += d_vector[coordinate]
    return vertices


def rotate_point(x: int, y: int, theta: float):
    return [
        x*cos(theta) - y*sin(theta),
        x*sin(theta) + y*cos(theta)
    ]


def fit_to_board(sides: int, x: int, y: int, size: float):
    length = size / {3: 3, 4: 2, 6: 1}[sides]**.5
    rotation = radians({3: 30, 4: 45, 6: 60}[sides])

    polygon = list(get_polygon_vertices(length, sides))

    condition = (x + y) % 2 == 1
    match sides:
        case 3:
            polygon = list(
                map(
                    lambda point: rotate_point(*point, radians(90) if condition else rotation),
                    polygon
                )
            )
            d_vector = x * size / 2, y * 3 ** .5 * size / 2 + size - (length / 2 if condition else 0)
        case 4:
            polygon = list(
                map(
                    lambda point: rotate_point(*point, rotation),
                    polygon
                )
            )
            d_vector = size * x, size * y
        case 6: d_vector = 3 * size * x / 2, 3 ** .5 * size * (y + (1/2 if x % 2 else 0))
        case _: d_vector = tuple()

    return move_polygon(polygon, d_vector)


if __name__ == "__main__":
    for sides in [3,  4, 6]:
        print(fit_to_board(sides, 2, 3, 100))
